package com.atguigu.gmall.item.service.impl;

import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.mall.cache.annotation.MallCache;
import com.atguigu.gmall.item.feign.SkuFeignClient;
import com.atguigu.mall.cache.service.CacheService;
import com.atguigu.gmall.item.service.SkuDetailService;
import com.atguigu.gmall.item.vo.CategoryView;
import com.atguigu.gmall.item.vo.SkuDetailVo;
import com.atguigu.gmall.product.entity.SkuImage;
import com.atguigu.gmall.product.entity.SkuInfo;
import com.atguigu.gmall.product.entity.SpuSaleAttr;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service
public class SkuDetailServiceImpl implements SkuDetailService {
    @Autowired
    SkuFeignClient skuFeignClient;
    @Autowired
    CacheService cacheService;
    @Autowired
    RedissonClient redissonClient;

    @Autowired
    ThreadPoolExecutor executor;


//    public SkuDetailVo getSkuDetailWithRedisson(Long skuId) {
//        //先去缓存中查询商品
//        String cacheKey = RedisConst.SKU_INFO_CACHE_KEY +skuId;
//        SkuDetailVo cacheData = cacheService.getCacheData(cacheKey);
//        if (cacheData==null){
//            //使用bitmap防止穿透攻击
//            boolean f =cacheService.existSkuIdByBitMap(skuId);
//            //ReentrantLock lock = new ReentrantLock();
//
//            if (f){
//                SkuDetailVo vo = null;
//                //lock:sku_info:49 //锁的粒度要细
//                String lockKey = RedisConst.LOCK_PREFIX + cacheKey;
//                RLock lock = redissonClient.getLock(lockKey);
//                //lock.lock();
//                boolean b = lock.tryLock();
//                if (b){
//                    try {
//                        //bitmap中有 数据库有 缓存没有
//                        //缓存没有需要回源
//
//                        vo = getSkuDetailVoFromRpc(skuId);
//                        //保存数据
//                        cacheService.saveCacheData(cacheKey,vo);
//                    }finally {
//                        lock.unlock();
//                    }
//
//
//                }else {
//                    try {
//                        Thread.sleep(500);
//                        return cacheData = cacheService.getCacheData(cacheKey);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
//                }
//
//
//                return vo;
//            }
//
//            //说明bitmap中没有 直接返回null
//            return null;
//
//        }
//        //回源
//        SkuDetailVo vo = getSkuDetailVoFromRpc(skuId);
//
//        return vo;
//    }

    //远程查询商品详情
    private SkuDetailVo getSkuDetailVoFromRpc(Long skuId) {
        SkuDetailVo vo = new SkuDetailVo();

        //基本信息

        CompletableFuture<SkuInfo> skuInfoAsync = CompletableFuture.supplyAsync(() -> {
            SkuInfo skuInfo = skuFeignClient.getSkuInfo(skuId).getData();
            return skuInfo;
        },executor);

        //商品图片
        CompletableFuture<Void> imageAsync = skuInfoAsync.thenAcceptAsync(skuInfo -> {
            List<SkuImage> skuImages = skuFeignClient.getSkuImages(skuId).getData();
            skuInfo.setSkuImageList(skuImages);


            //sku基本信息 以及图片
            vo.setSkuInfo(skuInfo);
        }, executor);


        CompletableFuture<Void> categorysAsync = skuInfoAsync.thenAcceptAsync(skuInfo -> {
            //sku所在的完整分类
            CategoryView categoryView = skuFeignClient.getSkuCategoryView(skuInfo.getCategory3Id()).getData();
            vo.setCategoryView(categoryView);
        }, executor);


        CompletableFuture<Void> saleAttrAsync = skuInfoAsync.thenAcceptAsync(skuInfo -> {
            //sku对应的spu定义的所有销售属性列表
            List<SpuSaleAttr> spuSaleAttrs = skuFeignClient.getSpuSaleAttrAndValue(skuInfo.getSpuId(), skuId).getData();
            vo.setSpuSaleAttrList(spuSaleAttrs);
        }, executor);


        CompletableFuture<Void> skuJsonAsync = skuInfoAsync.thenAcceptAsync(skuInfo -> {
            //sku各种组合的json
            String data = skuFeignClient.getSkuValueJson(skuInfo.getSpuId()).getData();
            vo.setValuesSkuJson(data);

        }, executor);

        CompletableFuture<Void> priceAsync = CompletableFuture.runAsync(() -> {
            //商品详情页价格
            Result<BigDecimal> skuPrice = skuFeignClient.getSkuPrice(skuId);
            vo.setSkuPrice(skuPrice.getData());
        }, executor);

        CompletableFuture.allOf(imageAsync,categorysAsync,saleAttrAsync,skuJsonAsync,priceAsync)
                .join();

        return vo;
    }

    //缓存的key：指定一个表达式 这样才能适配所以场景
    @MallCache(cacheKey = RedisConst.SKU_INFO_CACHE_KEY+"#{#args[0]}",
            bitmapIndex = "#{#args[0]}",
            bitmapKey = RedisConst.SKUID_BITMAP_KEY,
            ttl = 7,
            unit = TimeUnit.DAYS
    )//以后专注业务逻辑
    @Override
    public SkuDetailVo getSkuDetail(Long skuId) {
        return getSkuDetailVoFromRpc(skuId);
    }
}
